1 <!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
4 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8">
5 <meta http-equiv=
"Content-Style-Type" content=
"text/css">
7 <meta name=
"Generator" content=
"Cocoa HTML Writer">
8 <meta name=
"CocoaVersion" content=
"949.33">
9 <style type=
"text/css">
10 p
.p1
{margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica
}
11 p
.p2
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; min-height: 14.0px}
12 p
.p3
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
}
13 p
.p4
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #001bb9}
14 p
.p5
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
}
15 p
.p6
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; min-height: 12.0px}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #ad140d}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
}
18 p
.p9
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #0000bf}
19 p
.p10
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000}
20 p
.p11
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #bf0000}
21 p
.p12
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000; min-height: 12.0px}
22 p
.p13
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #0036ec}
23 p
.p14
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #0033dd}
24 span
.s1
{color: #000000}
25 span
.s2
{color: #606060}
26 span
.s3
{color: #001bb9}
27 span
.s4
{color: #007300}
28 span
.s5
{color: #0000bf}
29 span
.s6
{color: #2c7014}
30 span
.s7
{color: #0024f8}
31 span
.s8
{color: #0036ec}
32 span
.s9
{text-decoration: underline
; color: #0021e7}
33 span
.s10
{font: 12.0px Helvetica
}
34 span
.s11
{text-decoration: underline
; color: #0033dd}
35 span
.s12
{color: #002bf8}
36 span
.s13
{color: #003fdc}
37 span
.Apple-tab-span
{white-space:pre
}
41 <p class=
"p1"><b>Sequencing with Routines and Tasks
</b></p>
42 <p class=
"p2"><br></p>
43 <p class=
"p3">When you schedule a function (as in the Scheduling Events tutorial), the function always begins at the beginning and runs through to the end. For sequencing, it's more useful to have a control structure that can run part of the way through, return a value, and then pick up where it left off the next time it's needed. In SuperCollider, this is a Routine.
</p>
44 <p class=
"p2"><br></p>
45 <p class=
"p3">Routines can be used for data processing, e.g.
</p>
46 <p class=
"p2"><br></p>
47 <p class=
"p4"><span class=
"s1">r =
</span>Routine
<span class=
"s1">({
</span></p>
48 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">"abcde"</span>.yield;
</p>
49 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">"fghij"</span>.yield;
</p>
50 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">"klmno"</span>.yield;
</p>
51 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">"pqrst"</span>.yield;
</p>
52 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">"uvwxy"</span>.yield;
</p>
53 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">"z{|}~"</span>.yield;
</p>
55 <p class=
"p6"><br></p>
56 <p class=
"p7"><span class=
"s1">r.next;
<span class=
"Apple-tab-span"> </span></span>// get the next value from the Routine
</p>
57 <p class=
"p5">6.do({ r.next.postln });
</p>
58 <p class=
"p2"><br></p>
59 <p class=
"p3">The first time you call next, the routine yields
<b>"abcde"</b>. This yield value becomes the result of r.next, and is printed in the post window. On the second next call, execution picks up just after the first yield and continues with the second string, and so forth. When there is nothing more to yield, r.next returns nil.
</p>
60 <p class=
"p2"><br></p>
61 <p class=
"p3">We will come back to the use of routines for data generation. More important for sequencing is what happens when you schedule a routine on a clock, and the routine returns time values.
</p>
62 <p class=
"p2"><br></p>
63 <p class=
"p8"><b>Scheduling routines
</b></p>
64 <p class=
"p2"><br></p>
65 <p class=
"p3">Recall that, when you schedule a function on a clock, numbers returned by the function are treated as time values -- specifically, the amount of time until the function should execute again. The same thing happens with numbers yielded by a routine.
</p>
66 <p class=
"p2"><br></p>
67 <p class=
"p4"><span class=
"s1">r =
</span>Routine
<span class=
"s1">({
</span></p>
68 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s3">var
</span><span class=
"Apple-tab-span"> </span>delta;
</p>
69 <p class=
"p5"><span class=
"Apple-tab-span"> </span>loop {
</p>
70 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>delta = rrand(
1,
3) *
0.5;
</p>
71 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s2">"Will wait "</span>.post; delta.postln;
</p>
72 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>delta.yield;
</p>
73 <p class=
"p5"><span class=
"Apple-tab-span"> </span>}
</p>
75 <p class=
"p6"><br></p>
76 <p class=
"p5">r.next;
</p>
77 <p class=
"p6"><br></p>
78 <p class=
"p5"><span class=
"s3">TempoClock
</span>.default.sched(
0, r);
</p>
79 <p class=
"p6"><br></p>
80 <p class=
"p5">r.stop;
</p>
81 <p class=
"p2"><br></p>
82 <p class=
"p3">Now let's replace the posting statements with instructions to play a synth. Preparation:
</p>
83 <p class=
"p2"><br></p>
85 <p class=
"p9">SynthDef
<span class=
"s1">(
</span><span class=
"s4">\singrain
</span><span class=
"s1">, {
</span>|freq =
440, amp =
0.2, sustain =
1|
</p>
86 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"s5">var
</span><span class=
"Apple-tab-span"> </span>sig;
</p>
87 <p class=
"p10"><span class=
"Apple-tab-span"> </span>sig =
<span class=
"s5">SinOsc
</span>.ar(freq,
0, amp) *
<span class=
"s5">EnvGen
</span>.kr(
<span class=
"s5">Env
</span>.perc(
0.01, sustain), doneAction:
2);
</p>
88 <p class=
"p11"><span class=
"s1"><span class=
"Apple-tab-span"> </span></span><span class=
"s5">Out
</span><span class=
"s1">.ar(
0, sig !
2);
<span class=
"Apple-tab-span"> </span></span>// sig !
2 is the same as [sig, sig]
</p>
89 <p class=
"p10">}).send(s);
</p>
90 <p class=
"p12"><br></p>
91 <p class=
"p9"><span class=
"s1">r =
</span>Routine
<span class=
"s1">({
</span></p>
92 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"s5">var
</span><span class=
"Apple-tab-span"> </span>delta;
</p>
93 <p class=
"p10"><span class=
"Apple-tab-span"> </span>loop {
</p>
94 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>delta = rrand(
1,
3) *
0.5;
</p>
95 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s5">Synth
</span>(
<span class=
"s4">\singrain
</span>, [freq: exprand(
200,
800), amp: rrand(
0.1,
0.5), sustain: delta *
0.8]);
</p>
96 <p class=
"p10"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>delta.yield;
</p>
97 <p class=
"p10"><span class=
"Apple-tab-span"> </span>}
</p>
98 <p class=
"p10">});
</p>
100 <p class=
"p2"><br></p>
101 <p class=
"p3">Scheduling a routine makes a certain sense, but playing a routine seems more intuitive.
</p>
102 <p class=
"p2"><br></p>
103 <p class=
"p5">r.play;
</p>
104 <p class=
"p6"><br></p>
105 <p class=
"p5">r.stop;
</p>
106 <p class=
"p2"><br></p>
107 <p class=
"p3">There you go -- our first sequence.
</p>
108 <p class=
"p2"><br></p>
109 <p class=
"p8"><b>Pause and resume: Task
</b></p>
110 <p class=
"p2"><br></p>
111 <p class=
"p3">Routines have one sticky little characteristic that can limit their usefulness as musical objects. Once you stop a routine, you can only start it over again from the beginning. There is no way to replay the routine from the point where it was stopped.
</p>
112 <p class=
"p2"><br></p>
113 <p class=
"p3">Task is a variation that can be paused and resumed at will. For example, let's iterate over a C major scale. Note that all of SuperCollider's control structures are valid inside a Routine or Task. Note also that we can use 'wait' as a synonym for 'yield'.
</p>
114 <p class=
"p2"><br></p>
116 <p class=
"p5">t =
<span class=
"s3">Task
</span>({
</p>
117 <p class=
"p5"><span class=
"Apple-tab-span"> </span>loop {
</p>
118 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>[
60,
62,
64,
65,
67,
69,
71,
72].do({
<span class=
"s3">|midi|
</span></p>
119 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Synth
</span>(
<span class=
"s6">\singrain
</span>, [freq: midi.midicps, amp:
0.2, sustain:
0.1]);
</p>
120 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>0.125.wait;
</p>
121 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>});
</p>
122 <p class=
"p5"><span class=
"Apple-tab-span"> </span>}
</p>
123 <p class=
"p5">}).play;
</p>
125 <p class=
"p6"><br></p>
126 <p class=
"p7">// probably stops in the middle of the scale
</p>
127 <p class=
"p5">t.stop;
</p>
128 <p class=
"p6"><br></p>
129 <p class=
"p7"><span class=
"s1">t.play;
<span class=
"Apple-tab-span"> </span></span>// should pick up with the next note
</p>
130 <p class=
"p6"><br></p>
131 <p class=
"p5">t.stop;
</p>
132 <p class=
"p2"><br></p>
133 <p class=
"p3">Task will be used for the remainder of this tutorial.
</p>
134 <p class=
"p2"><br></p>
135 <p class=
"p8"><b>When do you want to start?
</b></p>
136 <p class=
"p2"><br></p>
137 <p class=
"p3">By default,
<b>play
</b> applied to a Task starts the Task immediately. Most of the time, many tasks will be running simultaneously, and they should be synchronized. While there might be a virtuoso out there somewhere who can hit the enter key at just right time for precise sync, most of us would prefer a more reliable mechanism.
</p>
138 <p class=
"p2"><br></p>
139 <p class=
"p3">Play takes several arguments to control its behavior.
</p>
140 <p class=
"p2"><br></p>
141 <p class=
"p5">aRoutine.play(clock, quant)
</p>
142 <p class=
"p5">aTask.play(argClock, doReset, quant)
</p>
143 <p class=
"p2"><br></p>
144 <p class=
"p3"><b>clock
</b> (Routine) or
<b>argClock
</b> (Task): Which clock should handle scheduling for this sequence
</p>
145 <p class=
"p3"><b>doReset
</b> (Task only): If true, reset the sequence to the beginning before playing; if false (default), resume
</p>
146 <p class=
"p3"><b>quant
</b>: A specification of the exact starting time
</p>
147 <p class=
"p2"><br></p>
148 <p class=
"p3">The quant argument uses a basic model of two numbers, which can be related to the western concept of meter:
</p>
149 <p class=
"p2"><br></p>
150 <p class=
"p3">quant: Corresponds roughly to bar length; the current time is rounded up to the next multiple of this number
</p>
151 <p class=
"p3">phase: Position within the bar (
0 = beginning of the bar)
</p>
152 <p class=
"p2"><br></p>
153 <p class=
"p3">For convenience, if you just want to start at the beginning of the bar, you can give the bar length as a number. An array of two numbers tells SuperCollider the bar length and the phase.
</p>
154 <p class=
"p2"><br></p>
155 <p class=
"p3">To see how this works in practice, let's take the C major scale above and play two copies of it slightly offset. We'll slow the rhythm down to
16th-notes (
0.25) and start the second one
8th-note into the bar. We will need two tasks to do this, which will be manufactured in a function.
</p>
156 <p class=
"p2"><br></p>
157 <p class=
"p5">f = {
</p>
158 <p class=
"p4"><span class=
"s1"><span class=
"Apple-tab-span"> </span></span>Task
<span class=
"s1">({
</span></p>
159 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>loop {
</p>
160 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>[
60,
62,
64,
65,
67,
69,
71,
72].do({
<span class=
"s3">|midi|
</span></p>
161 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Synth
</span>(
<span class=
"s6">\singrain
</span>, [freq: midi.midicps, amp:
0.2, sustain:
0.1]);
</p>
162 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>0.25.wait;
</p>
163 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>});
</p>
164 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
165 <p class=
"p5"><span class=
"Apple-tab-span"> </span>});
</p>
167 <p class=
"p6"><br></p>
168 <p class=
"p7"><span class=
"s1">t = f.value.play(quant:
4);
<span class=
"Apple-tab-span"> </span></span>// start on next
4-beat boundary
</p>
169 <p class=
"p6"><br></p>
170 <p class=
"p7"><span class=
"s1">u = f.value.play(quant: [
4,
0.5]);
<span class=
"Apple-tab-span"> </span></span>// next
4-beat boundary + a half-beat
</p>
171 <p class=
"p6"><br></p>
172 <p class=
"p5">t.stop; u.stop;
</p>
173 <p class=
"p2"><br></p>
174 <p class=
"p8"><b>Using data routines in note sequencing
</b></p>
175 <p class=
"p2"><br></p>
176 <p class=
"p3">The previous example controls the generation of one parameter (pitch) by looping over an array inside the Task. What if you want to control several parameters?
</p>
177 <p class=
"p2"><br></p>
178 <p class=
"p3">Remember that routines can also generate data, in addition to their scheduling capabilities. You can refer to as many data routines as you want in your sequence.
</p>
179 <p class=
"p2"><br></p>
181 <p class=
"p5"><span class=
"s3">var
</span> midi, dur;
</p>
182 <p class=
"p5">midi =
<span class=
"s3">Routine
</span>({
</p>
183 <p class=
"p5"><span class=
"Apple-tab-span"> </span>[
60,
72,
71,
67,
69,
71,
72,
60,
69,
67].do({
<span class=
"s3">|midi|
</span> midi.yield });
</p>
184 <p class=
"p5">});
</p>
185 <p class=
"p5">dur =
<span class=
"s3">Routine
</span>({
</p>
186 <p class=
"p5"><span class=
"Apple-tab-span"> </span>[
2,
2,
1,
0.5,
0.5,
1,
1,
2,
2,
3].do({
<span class=
"s3">|dur|
</span> dur.yield });
</p>
187 <p class=
"p5">});
</p>
188 <p class=
"p6"><br></p>
189 <p class=
"p4">SynthDef
<span class=
"s1">(
</span><span class=
"s6">\smooth
</span><span class=
"s1">, {
</span>|freq =
440, sustain =
1, amp =
0.5|
</p>
190 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s3">var
</span><span class=
"Apple-tab-span"> </span>sig;
</p>
191 <p class=
"p5"><span class=
"Apple-tab-span"> </span>sig =
<span class=
"s3">SinOsc
</span>.ar(freq,
0, amp) *
<span class=
"s3">EnvGen
</span>.kr(
<span class=
"s3">Env
</span>.linen(
0.05, sustain,
0.1), doneAction:
2);
</p>
192 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(
0, sig !
2)
</p>
193 <p class=
"p5">}).send(s);
</p>
194 <p class=
"p6"><br></p>
195 <p class=
"p5">r =
<span class=
"s3">Task
</span>({
</p>
196 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s3">var
</span><span class=
"Apple-tab-span"> </span>delta;
</p>
197 <p class=
"p5"><span class=
"Apple-tab-span"> </span>while {
</p>
198 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>delta = dur.next;
</p>
199 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>delta.notNil
</p>
200 <p class=
"p5"><span class=
"Apple-tab-span"> </span>} {
</p>
201 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Synth
</span>(
<span class=
"s6">\smooth
</span>, [freq: midi.next.midicps, sustain: delta]);
</p>
202 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>delta.yield;
</p>
203 <p class=
"p5"><span class=
"Apple-tab-span"> </span>}
</p>
204 <p class=
"p5">}).play(quant:
<span class=
"s3">TempoClock
</span>.default.beats +
1.0);
</p>
206 <p class=
"p2"><br></p>
207 <p class=
"p3">Note that routines are used for the data, but task is used for play. Also, unlike the previous infinite sequences, this one stops when it runs out of data. That's the purpose of the while loop -- it continues only as long as the 'dur' data stream keeps pumping out values. (See the
<a href=
"../../Language/Control-Structures.html"><span class=
"s7">Control-Structures
</span></a> helpfile for more on
<b>while
</b>.)
</p>
208 <p class=
"p2"><br></p>
209 <p class=
"p3">There must be an easier way to write the data streams -- repeatedly writing the same do loop is certainly inconvenient. In fact, there is such a way, covered in the next tutorial: sequencing with patterns.
</p>
210 <p class=
"p2"><br></p>
211 <p class=
"p3">(Here we use quant simply to delay Task onset by one beat.
<span class=
"Apple-converted-space"> </span>This is because it takes some time for the synthdef to be ready for use on the server. Without it, the first note would not be heard.)
</p>
212 <p class=
"p2"><br></p>
213 <p class=
"p8"><b>A note on server messaging and timing
</b></p>
214 <p class=
"p2"><br></p>
215 <p class=
"p3">Using Synth as in the preceding examples can result in small but sometimes noticeable timing inaccuracies. This is because it takes a short time to transmit OSC messages from your code to the server, and this time is not always constant. SuperCollider deals with this by giving you the option to send the message with a timestamp telling the server exactly when the message should take effect. A
<b>latency
</b> value is used to calculate the timestamp.
</p>
216 <p class=
"p2"><br></p>
217 <p class=
"p3">Latency works by adding itself to the current time on the clock. If all the messages go out with the same latency value, their timing will be precise relative to each other and to the clock. The
<a href=
"../../ServerArchitecture/ServerTiming.html"><span class=
"s8">ServerTiming
</span></a> help file explains in more detail how this works, but you don't really need to know all of that in order to use it. The main point is to use a consistent, small latency value for perfect timing. (A Server object has a latency variable that you can use for consistency.)
</p>
218 <p class=
"p2"><br></p>
219 <p class=
"p3">Here's an example illustrating the kinds of inaccuracy you might hear. The inaccuracy may be more or less noticeable on different systems. It uses the \singrain SynthDef above and plays
10 notes per second.
</p>
220 <p class=
"p2"><br></p>
222 <p class=
"p5">t =
<span class=
"s3">Task
</span>({
</p>
223 <p class=
"p5"><span class=
"Apple-tab-span"> </span>loop {
</p>
224 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Synth
</span>(
<span class=
"s6">\singrain
</span>, [freq: exprand(
400,
1200), sustain:
0.08]);
</p>
225 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>0.1.wait;
</p>
226 <p class=
"p5"><span class=
"Apple-tab-span"> </span>}
</p>
227 <p class=
"p5">}).play;
</p>
229 <p class=
"p6"><br></p>
230 <p class=
"p5">t.stop;
</p>
231 <p class=
"p2"><br></p>
232 <p class=
"p3">The easiest way to add latency to your outgoing Synths is with the Server
<b>makeBundle
</b> method. Don't worry about how it works for now -- the important thing is that it uses the first value for latency, and runs the messages produced by the function according to that latency.
</p>
233 <p class=
"p2"><br></p>
235 <p class=
"p5">t =
<span class=
"s3">Task
</span>({
</p>
236 <p class=
"p5"><span class=
"Apple-tab-span"> </span>loop {
</p>
237 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>s.makeBundle(s.latency, {
</p>
238 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Synth
</span>(
<span class=
"s6">\singrain
</span>, [freq: exprand(
400,
1200), sustain:
0.08]);
</p>
239 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>});
</p>
240 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>0.1.wait;
</p>
241 <p class=
"p5"><span class=
"Apple-tab-span"> </span>}
</p>
242 <p class=
"p5">}).play;
</p>
244 <p class=
"p6"><br></p>
245 <p class=
"p5">t.stop;
</p>
246 <p class=
"p2"><br></p>
247 <p class=
"p3">See also:
</p>
248 <p class=
"p2"><br></p>
249 <p class=
"p13"><span class=
"s9"><a href=
"../../Core/Kernel/Routine.html">Routine
</a></span><span class=
"s1"><span class=
"Apple-tab-span"> </span><a href=
"../../Scheduling/Task.html"><span class=
"s10">Task
</span></a><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><a href=
"../../Scheduling/Quant.html"><span class=
"s10">Quant
</span></a></span></p>
250 <p class=
"p14"><span class=
"s9"><a href=
"../../ServerArchitecture/ServerTiming.html">ServerTiming
</a></span><span class=
"s8"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><a href=
"../../ServerArchitecture/bundledCommands.html"><span class=
"s11">Bundled Server Messages
</span></a></span></p>
251 <p class=
"p2"><br></p>
252 <p class=
"p8"><b>Suggested Exercise:
</b></p>
253 <p class=
"p2"><br></p>
254 <p class=
"p3">Make a more interesting SynthDef to replace the \smooth SynthDef. Use more arguments for greater variability. Then change the data streams in the 'Over the Rainbow' example and add new data streams to play a different tune, more expressively.
</p>
255 <p class=
"p2"><br></p>
256 <p class=
"p3">____________________
</p>
257 <p class=
"p2"><br></p>
258 <p class=
"p3">This document is part of the tutorial
<b>Getting Started With SuperCollider
</b>.
</p>
259 <p class=
"p2"><br></p>
260 <p class=
"p3">Click here to go on to the next section:
<a href=
"Sequencing with Patterns.html"><span class=
"s12">Sequencing with Patterns
</span></a></p>
261 <p class=
"p2"><br></p>
262 <p class=
"p3">Click here to return to the table of Contents:
<a href=
"Getting Started With SC.html"><span class=
"s13">Getting Started With SC
</span></a></p>